package com.fs.system.college_admin.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.fs.system.college_admin.domain.Speciality;
import com.fs.system.college_admin.mapper.CollegeAdminSpecialityMapper;
import com.fs.system.college_admin.service.CollegeAdminSpecialityService;
import com.fs.system.common.ResponseData;
import com.fs.system.student.domain.ApplicationRecord;
import com.fs.system.student.domain.Student;
import com.fs.system.student.mapper.StudentMapper;
import com.fs.system.student.service.ApplicationRecordService;
import com.fs.system.student.service.StudentService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/collegeAdminData")
public class CollegeDataController {

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private StudentService studentService;

    @Resource
    private CollegeAdminSpecialityMapper collegeAdminSpecialityMapper;

    @Resource
    private ApplicationRecordService applyRecordService;

    @Resource
    private CollegeAdminSpecialityService collegeAdminSpecialityService;

    /**
     * 柱状图数据
     * @return 返回各专业学生人数及数据有效性标识
     */
    @GetMapping("/barDataStuCount")
    public ResponseData barDataStuCount(@RequestParam Long collegeId){
        Map<String,Object> resMap = new HashMap<>();
        Student queryStudent = new Student();
        queryStudent.setCollegeId(collegeId);
        //获取当前学院的学生数
        List<Student> dbStudentList = studentMapper.getStudentInfo(queryStudent);
        //首先过滤掉学生专业为null的学生
        List<Student> validDbStudentList = dbStudentList.stream().filter(student -> student.getSpecialityId() != null).collect(Collectors.toList());

        //先封装横轴数据（学院）
        Speciality querySpeciality = new Speciality();
        querySpeciality.setCollegeId(collegeId);
        List<Speciality> specialityList = collegeAdminSpecialityMapper.selectAllSpecialityByCollege(querySpeciality);
        //通过stream流方式
        Set<String> specialityNames = specialityList.stream().map(Speciality::getName).collect(Collectors.toSet());
        resMap.put("specialityNames",specialityNames);  //横轴x的数据：封装专业名称

        List<Long> studentCountList = new ArrayList<>();
        boolean hasData = false;
        for (String specialityName : specialityNames) {
            long count = validDbStudentList.stream().filter(student -> student.getSpecialityName().equals(specialityName)).count();
            studentCountList.add(count);
            if (count > 0) hasData = true; // 只要有一个专业有学生数据，即认为有数据
        }
        resMap.put("studentCountList",studentCountList); //y轴的数据：封装本院专业对应学生数量
        resMap.put("hasData", hasData); // 添加数据有效性标识

        return new ResponseData("200","获取成功",resMap);
    }

    /**
     * 折线图数据
     * @return 返回近两周本院学生活跃账号数量及数据有效性标识
     */
    @GetMapping("/lineDataUserCount")
    public ResponseData lineData(@RequestParam Long collegeId){
        Map<String,Object> resMap = new HashMap<>();
        Date nowDay = new Date(); //当前时间
        DateTime startDate = DateUtil.offsetDay(nowDay, -14);  //当前时间往前推14天(起始时间)
        List<DateTime> dateTimeList = DateUtil.rangeToList(startDate, nowDay, DateField.DAY_OF_YEAR);

        //获取指定日期格式的日期字符串
        List<String> dateStrList = dateTimeList.stream()
                .map(dateTime -> DateUtil.format(dateTime, "MM月dd日"))
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
        resMap.put("dateStrList",dateStrList);  //x轴数据

        List<Integer> countList = new ArrayList<>();
        boolean hasData = false;
        for (DateTime dateTime : dateTimeList) {
            DateTime startOfDay = DateUtil.beginOfDay(dateTime);
            DateTime endOfDay = DateUtil.endOfDay(dateTime);
            LocalDateTime startLocalDateTime = startOfDay.toLocalDateTime();
            LocalDateTime endLocalDateTime = endOfDay.toLocalDateTime();

            //查询本院部的对应每个时间段内学生活跃账号数量
            Integer count = studentService.selectUserCountByDateTime(startLocalDateTime, endLocalDateTime, collegeId);
            countList.add(count);
            if (count > 0) hasData = true; // 只要有一天有活跃数据，即认为有数据
        }
        resMap.put("countList", countList);  //y轴数据
        resMap.put("hasData", hasData); // 添加数据有效性标识

        return new ResponseData("200","获取成功",resMap);
    }

    /**
     * 饼图数据
     * @return 本院各专业学生提交材料数量及数据有效性标识
     */
    @GetMapping("/pieDataStuApplyRecord")
    public ResponseData pieData(@RequestParam Long collegeId){
        List<Map<String,Object>> resList = new ArrayList<>();
        Speciality querySpeciality = new Speciality();
        querySpeciality.setCollegeId(collegeId);
        List<Speciality> specialityList = collegeAdminSpecialityMapper.selectAllSpecialityByCollege(querySpeciality);
        Set<Long> specialityIds = specialityList.stream().map(Speciality::getSpecialityId).collect(Collectors.toSet());

        //获取本院学生的申请记录
        List<ApplicationRecord> applicationRecords = applyRecordService.selectApplyRecordList(null);
        List<ApplicationRecord> validDbApplicationRecordList = applicationRecords.stream()
                .filter(applicationRecord -> applicationRecord.getStuId() != null)
                .collect(Collectors.toList());

        boolean hasData = false;
        for (Long specialityId : specialityIds) {
            HashMap<String, Object> map = new HashMap<>();
            Speciality dbSpeciality = collegeAdminSpecialityService.selectSpecialityById(specialityId);
            map.put("name", dbSpeciality.getName());

            long count = validDbApplicationRecordList.stream()
                    .filter(applicationRecord -> applicationRecord.getSpecialityId().equals(specialityId))
                    .count();
            map.put("value", count);
            resList.add(map);

            if (count > 0) hasData = true; // 只要有一个专业有提交记录，即认为有数据
        }

        // 将hasData添加到响应数据中，但保持原有列表结构不变
        Map<String, Object> result = new HashMap<>();
        result.put("data", resList); // 保持原有列表结构
        result.put("hasData", hasData); // 添加数据有效性标识

        return new ResponseData("200", "获取成功", result);
    }

    /**
     * 柱状图数据
     * @return 返回各专业学生学分合格统计及数据有效性标识
     */
    @GetMapping("/barDataStuScoreCount")
    public ResponseData barDataStuScoreCount(@RequestParam Long collegeId){
        Map<String,Object> resMap = new HashMap<>();
        Student queryStudent = new Student();
        queryStudent.setCollegeId(collegeId);
        //获取当前学院的学生数
        List<Student> dbStudentList = studentMapper.getStudentInfo(queryStudent);
        //首先过滤掉学生专业为null的学生
        List<Student> validDbStudentList = dbStudentList.stream().filter(student -> student.getSpecialityId() != null).collect(Collectors.toList());

        Speciality querySpeciality = new Speciality();
        querySpeciality.setCollegeId(collegeId);
        List<Speciality> specialityList = collegeAdminSpecialityMapper.selectAllSpecialityByCollege(querySpeciality);
        Set<String> specialityNames = specialityList.stream().map(Speciality::getName).collect(Collectors.toSet());
        resMap.put("specialityNames",specialityNames);  //横轴x的数据：封装专业名称

        //y轴(1)的数据：合格人数
        List<Long> stuScoreSuccessCountList = new ArrayList<>();
        //y轴(2)的数据：不合格人数
        List<Long> stuScoreErrorCountList = new ArrayList<>();
        //y轴(3)的数据：专业总人数
        List<Long> studentCountList = new ArrayList<>();

        boolean hasData = false;
        for (String specialityName : specialityNames) {
            long successCount = validDbStudentList.stream()
                    .filter(student -> student.getSpecialityName().equals(specialityName) && student.getScore() >= 8)
                    .count();
            long errorCount = validDbStudentList.stream()
                    .filter(student -> student.getSpecialityName().equals(specialityName) && student.getScore() < 8)
                    .count();
            long totalCount = validDbStudentList.stream()
                    .filter(student -> student.getSpecialityName().equals(specialityName))
                    .count();

            stuScoreSuccessCountList.add(successCount);
            stuScoreErrorCountList.add(errorCount);
            studentCountList.add(totalCount);

            if (totalCount > 0) hasData = true; // 只要有一个专业有学生数据，即认为有数据
        }

        resMap.put("stuScoreSuccessCountList", stuScoreSuccessCountList);
        resMap.put("stuScoreErrorCountList", stuScoreErrorCountList);
        resMap.put("studentCountList", studentCountList);
        resMap.put("hasData", hasData); // 添加数据有效性标识

        return new ResponseData("200", "获取成功", resMap);
    }
}